<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WebGL 绘制一个渐变色</title>
</head>

<body>
    <canvas id="webglCanvas" width="400" height="400"></canvas>
    <script>
        const canvas = document.getElementById('webglCanvas');
        const gl = canvas.getContext('webgl');

        // // 定义矩形的顶点坐标和颜色
        // const vertices = [
        // 0.5, 0.5, 0.0, 1.0,
        // 0.5, -0.5, 0.0, 1.0,
        // -0.5, -0.5, 0.0, 1.0,
        // -0.5, 0.5, 0.0, 1.0
        // ];

        const vertices = new Float32Array([
            -0.5, -0.5, // 左下角  
            0.5, -0.5, // 右下角  
            -0.5, 0.5,   // 顶部 
            0.5, 0.5   // 顶部  
        ]);

        // 创建缓冲区对象并绑定
        const buffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, buffer);

        // 将顶点数据传输到缓冲区
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

        // 定义顶点着色器源代码  
        const vertexShaderSource = `  
        precision mediump float;
        attribute vec2 position;  
        // varying vec4 color;  
        void main() {  
            gl_Position = vec4(position, 0.0, 1.0);  
            // color = vec4(1.0, 1.0, 1.0, 1.0);  
        }  
        `;

        // 定义片元着色器源代码  
        const fragmentShaderSource = `  
        precision mediump float;
        uniform vec4 u_color;  
        void main() {  
            gl_FragColor = u_color;
        }  
        `;

        // 创建顶点着色器对象并编译  
        const vertexShader = gl.createShader(gl.VERTEX_SHADER);
        gl.shaderSource(vertexShader, vertexShaderSource);
        gl.compileShader(vertexShader);

        // 检查顶点着色器是否编译成功  
        if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
            console.error('顶点着色器编译失败:', gl.getShaderInfoLog(vertexShader));
            // 这里可能需要处理错误，比如返回或抛出异常  
        }

        // 创建片元着色器对象并编译  
        const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
        gl.shaderSource(fragmentShader, fragmentShaderSource);
        gl.compileShader(fragmentShader);

        // 检查片元着色器是否编译成功  
        if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
            console.error('片元着色器编译失败:', gl.getShaderInfoLog(fragmentShader));
            // 这里同样需要处理错误  
        }

        // 创建并链接程序  
        const program = gl.createProgram();
        gl.attachShader(program, vertexShader);
        gl.attachShader(program, fragmentShader);
        gl.linkProgram(program);

        // 检查程序是否链接成功  
        if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
            console.error('程序链接失败:', gl.getProgramInfoLog(program));
            // 处理错误  
        }

        // 使用程序  
        gl.useProgram(program);

        // 设置顶点属性
        const positionAttribute = gl.getAttribLocation(program, "position");
        gl.enableVertexAttribArray(positionAttribute);
        // gl.vertexAttribPointer(positionAttribute, 2, gl.FLOAT, false, 4 * sizeof(Float32Array), 0);
        gl.vertexAttribPointer(positionAttribute, 2, gl.FLOAT, false, 0, 0);
        // 获取 uniform 位置
        const u_color = gl.getUniformLocation(program, "u_color");
        // 设置新的颜色值
        gl.uniform4f(u_color, 0.0, 0.0, 1.0, 1.0);

        // // 清除画布并绘制三角形  
        // gl.clearColor(0.0, 0.0, 0.0, 1.0);
        // gl.clear(gl.COLOR_BUFFER_BIT);
        // // 绘制矩形
        // gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);



        // 进行 bloom 效果的后期处理代码示例

        // 存储模糊后的图像
        const framebuffer = gl.createFramebuffer();
        gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);

        // 创建纹理
        const texture = gl.createTexture();
        gl.bindTexture(gl.TEXTURE_2D, texture);

        // 设置纹理参数
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);

        // 分配纹理存储空间
        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 400, 400, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);



        for (let i = 0; i < 3; i++) {
            // 进行高斯模糊处理
            gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
            gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
            const blurRadius = 5.0; // 设置模糊半径
            gl.clearColor(0.0, 0.0, 0.0, 0.0);
            gl.clear(gl.COLOR_BUFFER_BIT);
            gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
            gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
        }



        // 将模糊后的图像与原始图像进行叠加
        gl.bindFramebuffer(gl.FRAMEBUFFER, null);
        gl.activeTexture(gl.TEXTURE0);
        gl.bindTexture(gl.TEXTURE_2D, texture);
        const uniformLocation = gl.getUniformLocation(program, "u_texture");
        gl.uniform1i(uniformLocation, 0);

        // 设置新的颜色值
        gl.uniform4f(u_color, 0.5, 1.0, 0.0, 1.0);


        // 清除画布并绘制三角形  
        gl.clearColor(0.0, 0.0, 0.0, 1.0);
        gl.clear(gl.COLOR_BUFFER_BIT);
        // 再次绘制矩形
        gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
    </script>
</body>

</html>